Using
zsh as default shell is perfect. Using
grml-zsh stuff to configure it, even better. Using
XTaran s config, way better. Using your own config, invaluable. Now, there is one thing that always bothered me: having all hosts I usually deal with in my
~/.ssh/config in order to have tab completion (and short names). I wanted to improve the situation and was kindly pointed in a different direction by
Myon, namely to just use the
~/.ssh/known_hosts for tab completion. How about that?
I started playing around with the config and, as it turns out, Axel already has something ready. Unfortunately, it didn t fulfill all my needs yet. That is because I have multiple
known_hosts files. Martin already filed a
bug to have ssh read
~/.ssh/known_hosts.d/* but that isn t resolved yet either, even though
upstream is aware of it. I thus had to point tab completion and ssh to multiple files by hand. But that s not too bad for now. Let s have a look:
Host *
HashKnownHosts no
Host *.your-work.com
User that-is-what-they-call-me-at-work
UserKnownHostsFile ~/.ssh/known_hosts.work
Host *.debian.org
UserKnownHostsFile ~/.ssh/known_hosts.debian
What am I doing? Well, we need to deactivate the hashing of known hosts. Otherwise your known_hosts files aren t readable as needed. Then you define your
known_hosts files for the domains you care about. Pretty straight forward.
Now, how about tab completion in zsh? Well, easy part actually:
[ -f ~/.ssh/config ] && : $ (A)ssh_config_hosts:=$ $ $ $ (@M)$ (f)"$(<~/.ssh/config)" :#Host * #Host :#*\** :#*\?*
[ -f ~/.ssh/known_hosts ] && : $ (A)ssh_known_hosts:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts)" %%\ * %%,*
[ -f ~/.ssh/known_hosts.work ] && : $ (A)ssh_known_hosts_work:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts.work)" %%\ * %%,*
[ -f ~/.ssh/known_hosts.debian ] && : $ (A)ssh_known_hosts_debian:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts.debian)" %%\ * %%,*
zstyle ':completion:*:hosts' hosts $ssh_config_hosts $ssh_known_hosts $ssh_known_hosts_work $ssh_known_hosts_debian
What's here? We read and parse your
~/.ssh/config for configured hosts, then we parse all your
known_hosts files which are for me:
~/.ssh/known_hosts,
~/.ssh/known_hosts.work, and
~/.ssh/known_hosts.debian. And lastly, all is added to zsh completion for hosts. That actually works. :)
Axel, that makes a diff for you looking like this:
diff --git a/zsh.d/70-completion b/zsh.d/70-completion
index e92e068..5abf5cc 100644
--- a/zsh.d/70-completion
+++ b/zsh.d/70-completion
@@ -8,6 +8,8 @@
[ -f ~/.ssh/config ] && : $ (A)ssh_config_hosts:=$ $ $ $ (@M)$ (f)"$(<~/.ssh/config)" :#Host * #Host :#*\** :#*\?*
[ -f ~/.ssh/known_hosts ] && : $ (A)ssh_known_hosts:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts)" %%\ * %%,*
+[ -f ~/.ssh/known_hosts.work ] && : $ (A)ssh_known_hosts_work:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts.work)" %%\ * %%,*
+[ -f ~/.ssh/known_hosts.debian ] && : $ (A)ssh_known_hosts_debian:=$ $ $ (f)"$(<$HOME/.ssh/known_hosts.debian)" %%\ * %%,*
-zstyle ':completion:*:*:*' hosts $ssh_config_hosts $ssh_known_hosts
+zstyle ':completion:*:hosts' hosts $ssh_config_hosts $ssh_known_hosts $ssh_known_hosts_work $ssh_known_hosts_debian
Care to merge?
Oh, and before I forget... Of course you don't need to check each and every host by yourself. Debian provides ssh keys for all hosts on master. Just do a
scp master.debian.org:/etc/ssh/ssh_known_hosts ~/.ssh/known_hosts.debian
and I'm sure, your security aware employer has such a file for you as well. Doesn't he? ;)